﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using System.Text.RegularExpressions;
using System.Globalization;

namespace TVGuide.Common
{
    public static class Utils
    {
        public static readonly int ZoneHour = 11; 
        /// <summary>
        /// Sending e-mail message to arm.tvguide@gmail.com adress, with the parsing issue described.
        /// </summary>
        /// <param name="message">Body of the e-mail.</param>
        /// 

        public static int LanguageSelect(string lng)
        {
            int language;
            if(lng == null)
                language = 1;
            
            switch (lng)
            {
                case "am":
                    language = 1;
                    break;
                case "en":
                    language = 2;
                    break;
                case "arm":
                    language = 1;
                    break;
                case "eng":
                    language = 2;
                    break;
                default:
                    language = 1;
                    break;
            }
            return language;
        }

        public static object ConvertDbNulls(object obj)
        {
            if (obj is DBNull)
                return null;
            else
                return obj;
        }

        public static string LanguageSelectToString(int lng)
        {
            string language="";

            switch (lng)
            {
                case 1:
                    language = "am";
                    break;
                case 2:
                    language = "en";
                    break;
                default:
                    language = "am";
                    break;
            }
            return language;
        }

        public static void SendNotificationMail(string message)
        {

            var client = new SmtpClient("smtp.gmail.com", 587)
            {
                Credentials = new NetworkCredential("arm.tvguide@gmail.com", "tvguidearm"),
                EnableSsl = true
            };
            //client.Send("arm.tvguide@gmail.com", "arm.tvguide@gmail.com", "Failed action", message);
        }

        /// <summary>
        /// Chopping all HTML tags from the string.
        /// </summary>
        /// <param name="input">Input string</param>
        /// <returns></returns>
        public static string removeHTMLTags(string input)
        {
            Regex rgxTagCutter = new Regex("</?[^>]*>");
            string stringWithoutTags = rgxTagCutter.Replace(input, " ");
            return stringWithoutTags;
        }

        /// <summary>
        /// Extension method for MatchCollection.
        /// </summary>
        /// <param name="inputCollection">Input MatchCollection.</param>
        /// <returns>
        /// Returns HTML tag free string list from MatchCollection.
        /// </returns>
        public static List<string> removeHTMLTags(this MatchCollection inputCollection)
        {
            List<string> outputList = new List<string>();
            foreach (Match inputMatch in inputCollection)
            {

                outputList.Add(removeHTMLTags(inputMatch.Value));
            }


            return outputList;
        }

        /// <summary>
        /// Seperates date and program name from string represented as: 00:00 Some TV Program
        /// </summary>
        /// <param name="input">Input string to extract time and program name.</param>
        /// <param name="time">Time of the program.</param>
        /// <param name="programName">Program name.</param>
        public static void seperateTimeProgramName(string input, out int hour, out int minutes, out string programName)
        {         
            string programDateStringPattern = @"(\d+)[:\.](\d{2})";
            Regex rgxProgramDateString = new Regex(programDateStringPattern);
            Match dateMatch = rgxProgramDateString.Match(removeHTMLTags(input));
            hour = Int32.Parse(dateMatch.Groups[1].Value);
            minutes = Int32.Parse(dateMatch.Groups[2].Value);
            if (hour==24)
            {

                hour = 0;
            }
            
            string programNameStringPattern = @"\d{2}:\d{2}(.*)";
            Regex rgxProgramNameString = new Regex(programNameStringPattern);
            Match programNameMatch = rgxProgramNameString.Match(input);
            programName = programNameMatch.Groups[1].Value;
        }

        public static void seperateTimeProgramName(string input, out int hour, out int minutes)
        {
            string dummy;
            seperateTimeProgramName(input, out hour, out minutes, out dummy);
        }


        public static string EscapeSpacialSymbols(string input)
        {
            string ntv = "NTV+";
            Regex rgxSpacialSymbol = new Regex("([+*?])");
            Match match = rgxSpacialSymbol.Match(input);
            string stringWithoutTags = rgxSpacialSymbol.Replace(input, "\\" + rgxSpacialSymbol.Match(ntv).Groups[1].Value);
            return stringWithoutTags;
        }

        static private int GetNumber(char ch)
        {
            int a = (int)ch;

            if (a >= 178 && a <= 253)
                return 178;

            if (a >= 1377 && a <= 1414)
                return 1377;

            if (a >= 1329 && a <= 1366)
                return 1329;

            return a;
        }
        public static String ArmUnicodeToArmAnsi(string UnicodeString)
        {
            string ansi_str = "";
            foreach (Char c in UnicodeString)
            {
                switch (GetIntervalNumber(c))
                {
                    case 1415: //ev
                        ansi_str += ((Char)168).ToString();
                        break;

                    case 1329: // TODO: to 1366
                        ansi_str += ((Char)((c - 1240) * 2)).ToString();
                        break;

                    case 1377: // TODO: to 1414
                        ansi_str += ((Char)((c - 1288) * 2 + 1)).ToString();
                        break;

                    case 1373: //`
                        ansi_str += ((Char)170).ToString();
                        break;

                    case 171: // <<
                        ansi_str += ((Char)167).ToString();
                        break;

                    case 187: // >>
                        ansi_str += ((Char)166).ToString();
                        break;

                    case 1371: // shesht
                        ansi_str += ((Char)176).ToString();
                        break;

                    case 1374: // ?
                        ansi_str += ((Char)177).ToString();
                        break;

                    default:
                        ansi_str += c;
                        break;
                }
            }

            return ansi_str; ;
        }

        static private int GetIntervalNumber(char ch)
        {
            int a = (int)ch;

            if (a >= 178 && a <= 253)
                return 178;

            if (a >= 1377 && a <= 1414)
                return 1377;

            if (a >= 1329 && a <= 1366)
                return 1329;

            return a;
        }

        public static String ArmToUnicode(string AsciiString)
        {
            string unicde_str = "";
            foreach (Char c in AsciiString)
            {
                switch (GetNumber(c))
                {
                    case 168: //ev
                        unicde_str += ((Char)1415).ToString();
                        break;

                    case 178: // TODO: to 253
                        unicde_str += ((Char)(((c % 2) * 48) + ((c - 178) / 2) + 1329)).ToString();
                        break;

                    case 170: //`
                        unicde_str += ((Char)1373).ToString();
                        break;

                    case 167: // <<
                        unicde_str += ((Char)171).ToString();
                        break;

                    case 166: // >>
                        unicde_str += ((Char)187).ToString();
                        break;

                    case 176: // shesht
                        unicde_str += ((Char)1371).ToString();
                        break;

                    case 177: // ?
                        unicde_str += ((Char)1374).ToString();
                        break;

                    case 171: // ,
                        unicde_str += ((Char)44).ToString();
                        break;

                    default:
                        unicde_str += c;
                        break;
                }
            }

            return unicde_str;
        }

        // private property
        private static String _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

        // public method for decoding
        public static String DecodeFromBase64String(String input)
        {
            String output = "";
            int chr1, chr2, chr3;
            int enc1, enc2, enc3, enc4;
            var i = 0;
            input = Regex.Replace(input, "[^A-Za-z0-9 + / =]g", "");
            //input =   input.Replace(/[^A-Za-z0-9\+\/\=]/g, "");

            while (i < input.Length)
            {

                enc1 = _keyStr.IndexOf(input[i++]);
                enc2 = _keyStr.IndexOf(input[i++]);
                enc3 = _keyStr.IndexOf(input[i++]);
                enc4 = _keyStr.IndexOf(input[i++]);

                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;

                output = output + (Char)(chr1);

                if (enc3 != 64)
                {
                    output = output + (Char)(chr2);
                }
                if (enc4 != 64)
                {
                    output = output + (Char)(chr3);
                }

            }
            output = _utf8_decode(output);
            return output;
        }
        // private method for UTF-8 decoding
        private static String _utf8_decode(String utftext)
        {
            String str = "";
            int i = 0;
            int c = 0, c1 = 0, c2 = 0, c3;

            while (i < utftext.Length)
            {

                c = utftext[i];

                if (c < 128)
                {
                    str += (Char)(c);
                    i++;
                }
                else if ((c > 191) && (c < 224))
                {
                    c2 = utftext[i + 1];
                    str += (Char)(((c & 31) << 6) | (c2 & 63));
                    i += 2;
                }
                else
                {
                    c2 = utftext[i + 1];
                    c3 = utftext[i + 2];
                    str += (Char)(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                    i += 3;
                }

            }
            return str;
        }

        public static DateTime ConvertToHyAMDate(string dateString)
        {
            
            //Հինգշաբթի, 10 Նոյեմբեր
            CultureInfo myCIintl = new CultureInfo("hy-AM", false);
            try
            {
                DateTime _date = Convert.ToDateTime(dateString, myCIintl);
                return _date;
            }
            catch (Exception)
            {
                
                // Need to validate start and end dates at client side, so we never come here
            }
           

            return new DateTime();
        }

        private static Dictionary<String, String> armToEng = new Dictionary<String, String>();
        private static void initArmToEng()
        {
            armToEng["ա"] = "a";
            armToEng["բ"] = "b";
            armToEng["գ"] = "g";
            armToEng["դ"] = "d";
            armToEng["ե"] = "e";
            armToEng["զ"] = "z";
            armToEng["է"] = "e";
            armToEng["ը"] = "@";
            armToEng["թ"] = "t";
            armToEng["ժ"] = "zh";
            armToEng["ի"] = "i";
            armToEng["լ"] = "l";
            armToEng["խ"] = "x";
            armToEng["ծ"] = "ts";
            armToEng["կ"] = "k";
            armToEng["հ"] = "h";
            armToEng["ձ"] = "dz";
            armToEng["ղ"] = "x";
            armToEng["ճ"] = "ch";
            armToEng["մ"] = "m";
            armToEng["յ"] = "y";
            armToEng["ն"] = "n";
            armToEng["շ"] = "sh";
            armToEng["ո"] = "o";
            armToEng["չ"] = "ch";
            armToEng["պ"] = "p";
            armToEng["ջ"] = "j";
            armToEng["ռ"] = "r";
            armToEng["ս"] = "s";
            armToEng["վ"] = "v";
            armToEng["տ"] = "t";
            armToEng["ր"] = "r";
            armToEng["ց"] = "c";
            armToEng["ու"] = "u";
            armToEng["փ"] = "p";
            armToEng["ք"] = "q";
            armToEng["և"] = "ev";
            armToEng["օ"] = "o";
            armToEng["ֆ"] = "f";
            armToEng["եւ"] = "ev";
            armToEng["Ա"] = "A";
            armToEng["Բ"] = "B";
            armToEng["Գ"] = "G";
            armToEng["Դ"] = "D";
            armToEng["Ե"] = "E";
            armToEng["Զ"] = "Z";
            armToEng["Է"] = "E";
            armToEng["Ը"] = "@";
            armToEng["Թ"] = "T";
            armToEng["Ժ"] = "Zh";
            armToEng["Ի"] = "I";
            armToEng["Լ"] = "L";
            armToEng["Խ"] = "X";
            armToEng["Ծ"] = "Ts";
            armToEng["Կ"] = "K";
            armToEng["Հ"] = "H";
            armToEng["Ձ"] = "Dz";
            armToEng["Ղ"] = "X";
            armToEng["Ճ"] = "Ch";
            armToEng["Մ"] = "M";
            armToEng["Յ"] = "Y";
            armToEng["Ն"] = "N";
            armToEng["Շ"] = "Sh";
            armToEng["Ո"] = "O";
            armToEng["Չ"] = "Ch";
            armToEng["Պ"] = "P";
            armToEng["Ջ"] = "J";
            armToEng["Ռ"] = "R";
            armToEng["Ս"] = "S";
            armToEng["Վ"] = "V";
            armToEng["Տ"] = "T";
            armToEng["Ր"] = "R";
            armToEng["Ց"] = "C";
            armToEng["Ու"] = "U";
            armToEng["ՈՒ"] = "U";
            armToEng["Փ"] = "P";
            armToEng["Ք"] = "Q";
            armToEng["ԵՎ"] = "Ev";
            armToEng["Եվ"] = "Ev";
            armToEng["Եւ"] = "Ev";
            armToEng["Օ"] = "O";
            armToEng["Ֆ"] = "F";
        }
        
        public static String armToEngChar(String inputString)
        {
            initArmToEng();
            StringBuilder sb = new StringBuilder();
            String val;
            for (int i = 0; i < inputString.Length; ++i)
            {
                switch (inputString[i])
                { 
                    case 'ո':
                        if (inputString.Length > i + 1 && i < inputString.Length - 1 && inputString[i + 1] == 'ւ')
                        {
                            sb.Append('u');
                            ++i;
                        }
                        else if (i == 0)
                            sb.Append("vo");
                        else
                            sb.Append("o");
                        break;
                    case 'ե':
                        if (inputString.Length > i +1 && (i < inputString.Length - 1 && inputString[i + 1] == 'ւ' || inputString[i + 1] == 'վ'))
                        {
                            sb.Append("ev");
                            ++i;
                        }
                        else
                            sb.Append('e');
                        break;
                    case 'Ո':
                        if (inputString.Length > i + 1 && (i < inputString.Length - 1 && inputString[i + 1] == 'ւ' || inputString[i + 1] == 'Ւ'))
                        {
                            sb.Append('U');
                            ++i;
                        }
                        else if (i == 0)
                            sb.Append("Vo");
                        else
                            sb.Append("O");
                        break;
                    case 'Ե':
                        if (inputString.Length > i + 1 &&  (i < inputString.Length - 1 && inputString[i + 1] == 'ւ' || inputString[i + 1] == 'Վ' || inputString[i + 1] == 'վ'))
                        {
                            sb.Append("Ev");
                            ++i;
                        }
                        else
                            sb.Append('E');
                        break;
                    default:
                        if (armToEng.TryGetValue(inputString[i].ToString(), out val))
                            sb.Append(val);
                        else
                            sb.Append(inputString[i]);
                        break;
                }
            }
            return sb.ToString();
        }

        private static Dictionary<String, String> ruToEng = new Dictionary<String, String>();
        private static void initRuToEng()
        {
            ruToEng["а"] = "a";
            ruToEng["б"] = "b";
            ruToEng["в"] = "v";
            ruToEng["г"] = "g";
            ruToEng["д"] = "d";
            ruToEng["е"] = "e";
            ruToEng["ё"] = "jo";
            ruToEng["ж"] = "zh";
            ruToEng["з"] = "z";
            ruToEng["и"] = "i";
            ruToEng["й"] = "j"; 
            ruToEng["к"] = "k";
            ruToEng["л"] = "l";
            ruToEng["м"] = "m";
            ruToEng["н"] = "n";
            ruToEng["о"] = "o";
            ruToEng["п"] = "p";
            ruToEng["р"] = "r";
            ruToEng["с"] = "s";
            ruToEng["т"] = "t";
            ruToEng["у"] = "u";
            ruToEng["ф"] = "f";
            ruToEng["х"] = "x";
            ruToEng["ц"] = "c";
            ruToEng["ч"] = "ch";
            ruToEng["ш"] = "sh";
            ruToEng["щ"] = "shh";
            ruToEng["ъ"] = "";
            ruToEng["ы"] = "y";
            ruToEng["ь"] = "'";
            ruToEng["э"] = "e";
            ruToEng["ю"] = "ju";
            ruToEng["я"] = "ja";
            ruToEng["А"] = "A";
            ruToEng["Б"] = "B";
            ruToEng["В"] = "V";
            ruToEng["Г"] = "G";
            ruToEng["Д"] = "D";
            ruToEng["Е"] = "E";
            ruToEng["Ё"] = "Jo";
            ruToEng["Ж"] = "Zh";
            ruToEng["З"] = "Z";
            ruToEng["И"] = "I";
            ruToEng["Й"] = "J"; 
            ruToEng["К"] = "K";
            ruToEng["Л"] = "L";
            ruToEng["М"] = "M";
            ruToEng["Н"] = "N";
            ruToEng["О"] = "O";
            ruToEng["П"] = "P";
            ruToEng["Р"] = "R";
            ruToEng["С"] = "S";
            ruToEng["Т"] = "T";
            ruToEng["У"] = "U";
            ruToEng["Ф"] = "F";
            ruToEng["Х"] = "X";
            ruToEng["Ц"] = "C";
            ruToEng["Ч"] = "Ch";
            ruToEng["Ш"] = "Sh";
            ruToEng["Щ"] = "Shh";
            ruToEng["Ъ"] = "";
            ruToEng["Ы"] = "Y";
            ruToEng["Ь"] = "'";
            ruToEng["Э"] = "E";
            ruToEng["Ю"] = "Ju";
            ruToEng["Я"] = "Ja"; 
        }

        public static String ruToEngChar(String inputString)
        {
            initRuToEng();
            StringBuilder sb = new StringBuilder();
            String val;
            for (int i = 0; i < inputString.Length; ++i)
            {
                if (ruToEng.TryGetValue(inputString[i].ToString(), out val))
                    sb.Append(val);
                else
                    sb.Append(inputString[i]);                        
            }
            return sb.ToString();
        }

    }
}
